// RectWindow.cpp
// by Charles Mc Auley
// "Programming AutoCAD 2000 with ObjectARX"

#include "StdArx.h"


RectWindow::RectWindow()
{
	// Initialize the rect Frame Thickness
	// and the internal Window Framing thickness

	rows = 1;
	cols = 1;
	rectFrameLen = 0.0;
	rectFrameHt	 = 0.0;

	lowLeftPt.set(0.0, 0.00);
}

RectWindow::~RectWindow()
{
	// Does nothing
}


void RectWindow::drawWindow(AcDbBlockTableRecord* pBlkTableRecord)
{
	AcGePoint2dArray outrFrame;
	AcDbPolyline* pFrame;
	AcDbObjectId plineId;
	AcGeVector2d vec;
	AcGePoint2d ll, lr, ur, ul;
	AcGePoint2d vrtxPt;
	double len, ht;
	Acad::ErrorStatus es;

	// Get the window length, height and start point
	len = getWindowLength();
	ht	= getWindowHeight();
	ll	= getWindowStartPoint();

	// Calculate the other 3 corner points
	// from ll
	vec.set(len, 0);
	lr = ll + vec;
	vec.set(0, ht);
	ur = lr + vec;
	ul = ll + vec;

	// Add the four calculated points to the array
	outrFrame.append(ll);
	outrFrame.append(lr);
	outrFrame.append(ur);
	outrFrame.append(ul);

	pFrame = new AcDbPolyline(4);

	for(int count = 0; count < outrFrame.length(); count++)
	{
		vrtxPt = outrFrame.at(count);
		pFrame->addVertexAt(count, vrtxPt);
	}

	pFrame->setClosed(Adesk::kTrue);

	es = pBlkTableRecord->appendAcDbEntity(plineId, pFrame);
	if(es != Acad::eOk)
	{
		acutPrintf("\nError in drawing window frame. ");
		if(pFrame != NULL)
		{
			delete pFrame;
		}

		return;
	}

	pFrame->close();

	return;
}


// Get and Set functions

int RectWindow::getWindowRows() const
{
	return rows;
}

int RectWindow::getWindowCols() const
{
	return cols;
}

double RectWindow::getWindowHeight() const
{
	return rectFrameHt;
}

double RectWindow::getWindowLength() const
{
	return rectFrameLen;
}

AcGePoint2d RectWindow::getWindowStartPoint() const
{
	return lowLeftPt;
}


void RectWindow::setWindowRows(int rowQty)
{
	rows = rowQty;
}

void RectWindow::setWindowCols(int colQty)
{
	cols = colQty;
}

void RectWindow::setWindowHeight(double windHeight)
{
	rectFrameHt = windHeight;
}

void RectWindow::setWindowLength(double windLength)
{
	rectFrameLen = windLength;
}


void RectWindow::setWindowStartPoint(AcGePoint2d lowLeftPoint)
{
	lowLeftPt = lowLeftPoint;
}

void RectWindow::addXdata()
{
	struct resbuf* prbX;
	char appname[] = {"CH8_APPS"};
	char windotype[] = {"Rect"};
	ads_name ename;
	AcDbObjectId entId;
	AcDbObject* pObj;

	AcGePoint2d sp(getWindowStartPoint());

	ads_point lwrleft;
	lwrleft[X] = sp.x;
	lwrleft[Y] = sp.y;
	lwrleft[Z] = 0.0;

	acdbRegApp("CH8_APPS");

	prbX = acutBuildList(AcDb::kDxfRegAppName, appname,
						 AcDb::kDxfXdAsciiString, windotype,
						 AcDb::kDxfXdInteger32, getWindowRows(),
						 AcDb::kDxfXdInteger32, getWindowCols(),
						 AcDb::kDxfXdReal, getWindowLength(),
						 AcDb::kDxfXdReal, getWindowHeight(),
						 AcDb::kDxfXdWorldXCoord, lwrleft,
						 RTNONE);
	

	// Get the last entity
	acdbEntLast(ename);
	// Get the entity object ID
	acdbGetObjectId(entId, ename);

	// Open the enity for a write operation
	acdbOpenObject(pObj, entId, AcDb::kForWrite);

	// Add the extended entity data to the entity
	pObj->setXData(prbX);

	pObj->close();

	acutRelRb(prbX);
}

void RectWindow::printXdata()
{
	struct resbuf* prbX;
	struct resbuf* pTemp;
	char appname[] = {"CH8_APPS"};
	ads_name ename;
	AcDbObjectId entId;
	AcDbObject* pObj;

	// Get the last entity
	acdbEntLast(ename);
	// Get the entity object ID
	acdbGetObjectId(entId, ename);

	// Open the enity for a write operation
	acdbOpenObject(pObj, entId, AcDb::kForRead);

	// Add the extended entity data to the entity
	prbX = pObj->xData(appname);

	pObj->close();

	// Print out the extended entity data
	// Here I know the order of the extended entity data
	pTemp = prbX;

	// Bypass the application name
	pTemp = pTemp->rbnext;
	acutPrintf("\nWindow Type = %s", pTemp->resval.rstring);

	pTemp = pTemp->rbnext;
	acutPrintf("\nRows = %d", pTemp->resval.rint);

	pTemp = pTemp->rbnext;
	acutPrintf("\nCols = %d", pTemp->resval.rint);

	pTemp = pTemp->rbnext;
	acutPrintf("\nLength = %.2lf", pTemp->resval.rreal);

	pTemp = pTemp->rbnext;
	acutPrintf("\nHeight = %.2lf", pTemp->resval.rreal);

	pTemp = pTemp->rbnext;
	acutPrintf("\nStart Point = (%.2lf, %.2lf)", pTemp->resval.rpoint[X], pTemp->resval.rpoint[Y]);


	acutRelRb(prbX);	
}
